/* global cornerstone */
import './ImageThumbnail.styl';

import { utils } from '@ohif/core';
import React, { useState, useEffect, createRef } from 'react';
import { useSelector } from 'react-redux';
import classNames from 'classnames';

import PropTypes from 'prop-types';
// import ViewportErrorIndicator from '../../viewer/ViewportErrorIndicator';
// import ViewportLoadingIndicator from '../../viewer/ViewportLoadingIndicator';

// TODO: How should we have this component depend on Cornerstone?
// - Passed in as a prop?
// - Set as external dependency?
// - Pass in the entire load and render function as a prop?
//import cornerstone from 'cornerstone-core';

function StackProgress({ displaySetInstanceUID }) {
  const { stackPercentComplete } = useSelector(state => {
    const { progress: progressMap } = state.loading;
    const progressData = progressMap[`StackProgress:${displaySetInstanceUID}`];
    const stackPercentComplete = progressData ? progressData.percentComplete : 0;
    return {
      stackPercentComplete,
    }
  });

  return stackPercentComplete !== undefined ? (
    <div className="image-thumbnail-progress">
      <div className="image-thumbnail-progress-bar">
        <div
          className={`image-thumbnail-progress-bar-inner ${stackPercentComplete >= 100 ? 'complete' : ''}`}
          style={{ width: `${stackPercentComplete}%` }}
        />
      </div>
    </div>
  ) : null;
}

StackProgress.propTypes = {
  displaySetInstanceUID: PropTypes.string.isRequired,
}

function ImageThumbnail(props) {
  const {
    width,
    height,
    imageSrc,
    imageId,
    error: propsError,
    displaySetInstanceUID,
  } = props;

  const [isLoading, setLoading] = useState(false);
  const [error, setError] = useState(false);
  const [image, setImage] = useState({});
  const canvasRef = createRef();

  let loadingOrError;
  let cancelablePromise;

  // if (propsError || error) {
  //   loadingOrError = <ViewportErrorIndicator />;
  // } else if (isLoading) {
  //   loadingOrError = <ViewportLoadingIndicator />;
  // }

  const shouldRenderToCanvas = () => {
    return imageId && !imageSrc;
  };

  const fetchImagePromise = () => {
    if (!cancelablePromise) {
      return;
    }

    setLoading(true);
    cancelablePromise
      .then(response => {
        setImage(response);
      })
      .catch(error => {
        if (error.isCanceled) return;
        setLoading(false);
        setError(true);
        throw new Error(error);
      });
  };

  const setImagePromise = () => {
    if (shouldRenderToCanvas()) {
      cancelablePromise = utils.makeCancelable(
        cornerstone.loadAndCacheImage(imageId)
      );
    }
  };

  const purgeCancelablePromise = () => {
    if (cancelablePromise) {
      cancelablePromise.cancel();
    }
  };

  useEffect(() => {
    return () => {
      purgeCancelablePromise();
    };
  }, [purgeCancelablePromise]);

  useEffect(() => {
    if (image.imageId) {
      cornerstone.renderToCanvas(canvasRef.current, image);
      setLoading(false);
    }
  }, [canvasRef, image, image.imageId]);

  useEffect(() => {
    if (!image.imageId || image.imageId !== imageId) {
      purgeCancelablePromise();
      setImagePromise();
      fetchImagePromise();
    }
  }, [fetchImagePromise, image.imageId, imageId, purgeCancelablePromise, setImagePromise]);

  return (
    <div className={classNames("image-thumbnail")}>
      <div className="image-thumbnail-canvas">
        {shouldRenderToCanvas() ? (
          <canvas ref={canvasRef} width={width} height={height} />
        ) : (
          <img
            className="static-image"
            src={imageSrc}
            //width={this.props.width}
            height={height}
            alt={''}
          />
        )}
      </div>
      {loadingOrError}
      <StackProgress displaySetInstanceUID={displaySetInstanceUID} />
      {isLoading && <div className="image-thumbnail-loading-indicator"></div>}
    </div>
  );
}

ImageThumbnail.propTypes = {
  imageSrc: PropTypes.string,
  imageId: PropTypes.string,
  error: PropTypes.bool,
  width: PropTypes.number,
  height: PropTypes.number,
  displaySetInstanceUID: PropTypes.string.isRequired,
};

ImageThumbnail.defaultProps = {
  error: false,
  width: 124,
  height: 96,
};

export default ImageThumbnail;
